/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.saar.penguin.give2.server;

import give.nlgserver.discretize.RegionDiscretizer;
import give.world.World;
import java.util.ArrayList;
import java.util.List;
import org.jgrapht.GraphPath;
import org.jgrapht.graph.DefaultEdge;

/**
 *
 * @author Boris Fersing
 */
public class HighLevelPath {

    private List<List<String>> paths = new ArrayList<List<String>>();
    private List<String> currentPath = null;
    private RegionDiscretizer r;

    public HighLevelPath(List<GraphPath<String, DefaultEdge>> gpaths, World w) {

        r = new RegionDiscretizer(w);

        if (gpaths == null) {
            this.paths = null;
            this.currentPath = null;
        } else {
            for (GraphPath<String, DefaultEdge> gpath : gpaths) {
                ArrayList<String> path = new ArrayList<String>();

                for (DefaultEdge edge : gpath.getEdgeList()) {
                    String source = edge.toString().toString().replaceAll("[() ]", "").split(":")[0];
                    String destination = edge.toString().toString().replaceAll("[() ]", "").split(":")[1];

                    RegionDiscretizer.RegionInfo sourceInfo = r.getRegionInformation(source);
                    RegionDiscretizer.RegionInfo destInfo = r.getRegionInformation(destination);

                    if (!path.contains(sourceInfo.getRoom())) {
                        path.add(sourceInfo.getRoom());
                    }
                    if (!path.contains(destInfo.getRoom())) {
                        path.add(destInfo.getRoom());
                    }
                }

                this.paths.add(path);
            }

            this.currentPath = this.paths.get(0);
        }
    }

    public String getLastPosition() {
        if (currentPath != null && !currentPath.isEmpty()) {
            return currentPath.get(currentPath.size() - 1);
        }

        return "";
    }

    public String getCurrentPosition() {
        if (currentPath != null) {
            return currentPath.get(0);
        }
        return "";
    }

    public List<String> getCurrentPath() {
        return currentPath;
    }

    public Boolean targetReached(){
        if (currentPath.size() <= 1){
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * Updates the path and returns true if the position was found in the paths.
     * @param position
     * @return true if the update was successful (position contained in at least 1 path). False otherwise.
     */
    public boolean updatePath(String position) {
        String room = r.getRegionInformation(position).getRoom();
        
        if (currentPath != null && paths != null) {
            // First try with the current path
            if (currentPath.lastIndexOf(room) != -1) {
                for (int i = 0; i < currentPath.lastIndexOf(room); i++) {
                    currentPath.remove(i);
                }
                return true;

            } else {
                paths.remove(currentPath);
                currentPath = null;

                // Search a new possible current path
                for (List<String> path : paths) {
                    if (path.contains(room)) {
                        currentPath = path;
                        break;
                    }
                }

                // If the path has been found, update it
                if (currentPath != null) {
                    for (int i = 0; i < currentPath.lastIndexOf(position); i++) {
                        currentPath.remove(i);
                    }
                    return true;
                }
                return false;
            }
        }
        return false;
    }
}
